<?php
namespace Home\Controller;
use Think\Controller;
/**
 * 微信支付接口
 */
 class WxpayController extends Controller{

	public function new_pay(){
		$orderid = I('get.ordersid');
		$money = I('get.money');
		$type = I('get.type');
		$total_fee=$money*100;
		session('orderid',$orderid);
		session('wx_money',$money);
		session('wx_order_type',$type);
		if ($type) {
			if ($type=='carry') {
			$obj=M('orders');
			}elseif ($type=='nocarry') {
				$obj=M('order');
			}
			$r=$obj->find($orderid);
		}
		
		
		
		//全局引入微信支付类 $this->redirect('Wxpay/new_pay',array('money'=>$money,'orderid'=>$id));
		Vendor('WxPayPubHelper.WxPayPubHelper');
		//使用jsapi接口
		$jsApi = new \JsApi_pub();
		
		//=========步骤1：网页授权获取用户openid============
		//通过code获得openid
		if (!isset($_GET['code']))
		{
			//触发微信返回code码
			$url = $jsApi->createOauthUrlForCode(\WxPayConf_pub::JS_API_CALL_URL);
			//$url = $jsApi->createOauthUrlForCode($this->fromurl);
			Header("Location: $url");
		}else
		{
			//获取code码，以获取openid
			$code = $_GET['code'];
			$jsApi->setCode($code);
			$openid = $jsApi->getOpenId();
			//$openid=session('openid');
		}
		$orderid=session('orderid');
		$money=session('wx_money');
		$type=session('wx_order_type');
		$res = array(
				'order_sn' =>$orderid,
				'order_amount' => $money
		);

		//=========步骤2：使用统一支付接口，获取prepay_id============
		//使用统一支付接口
		$unifiedOrder = new \UnifiedOrder_pub();
		$total_fee=$money*100;
		//设置统一支付接口参数
		//设置必填参数
		//appid已填,商户无需重复填写
		//mch_id已填,商户无需重复填写
		//noncestr已填,商户无需重复填写
		//spbill_create_ip已填,商户无需重复填写
		//sign已填,商户无需重复填写
		$unifiedOrder->setParameter("openid",$openid);//用户标识
		$unifiedOrder->setParameter("body","订单支付挪窝儿");//商品描述
		//自定义订单号，此处仅作举例
		$timeStamp = time();
		$out_trade_no = \WxPayConf_pub::APPID.$timeStamp;
		$unifiedOrder->setParameter("out_trade_no",$out_trade_no);//商户订单号
		$unifiedOrder->setParameter("total_fee",$total_fee);//总金额,注意单位是分
		$unifiedOrder->setParameter("notify_url",\WxPayConf_pub::NOTIFY_URL);//通知地址
		$unifiedOrder->setParameter("trade_type","JSAPI");//交易类型
		//非必填参数，商户可根据实际情况选填
		//$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号
		//$unifiedOrder->setParameter("device_info","XXXX");//设备号
		//$unifiedOrder->setParameter("attach","XXXX");//附加数据
		//$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间
		//$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间
		//$unifiedOrder->setParameter("goods_tag","XXXX");//商品标记
		//$unifiedOrder->setParameter("openid","XXXX");//用户标识
		//$unifiedOrder->setParameter("product_id","XXXX");//商品ID
		$prepay_id = $unifiedOrder->getPrepayId();
	 //=========步骤3：使用jsapi调起支付============
        $jsApi->setPrepayId($prepay_id);
        $jsApiParameters = $jsApi->getParameters();
        //var_dump($jsApiParameters);exit();
       // $wxconf = json_decode($jsApiParameters, true);
        /*if ($wxconf['package'] == 'prepay_id=') {
            $this->error('当前订单存在异常，不能使用支付');
        }*/
        $this->assign('res', $res);
        $this->assign('type', $type);
        $this->assign('orderid', $orderid);
        $this->assign('jsApiParameters', $jsApiParameters);
        $this->display('jsapi');
	}
	//异步通知url，商户根据实际开发过程设定
	public function notify_url() {
		vendor('WxPayPubHelper.WxPayPubHelper');
	    //使用通用通知接口
		$notify = new \Notify_pub();
		//存储微信的回调
		$xml = $GLOBALS['HTTP_RAW_POST_DATA'];	
		$notify->saveData($xml);
		//验证签名，并回应微信。
		//对后台通知交互时，如果微信收到商户的应答不是成功或超时，微信认为通知失败，
		//微信会通过一定的策略（如30分钟共8次）定期重新发起通知，
		//尽可能提高通知的成功率，但微信不保证通知最终能成功。
		if($notify->checkSign() == FALSE){
			$notify->setReturnParameter("return_code", "FAIL");//返回状态码
			$notify->setReturnParameter("return_msg", "签名失败");//返回信息
		}else{
			$notify->setReturnParameter("return_code", "SUCCESS");//设置返回码
		}
		$returnXml = $notify->returnXml();
		//==商户根据实际情况设置相应的处理流程，此处仅作举例=======
		//以log文件形式记录回调信息
		$log_name = "/notify_url.log";//log文件路径
		$this->log_result($log_name, "【接收到的notify通知】:\n".$xml."\n");


        $parameter = $notify->xmlToArray($xml);
        //$this->log_result($log_name, "【接收到的notify通知】:\n".$parameter."\n");
		if($notify->checkSign() == TRUE){
			if ($notify->data["return_code"] == "FAIL") {
                //此处应该更新一下订单状态，商户自行增删操作
                //$this->log_result($log_name, "【通信出错】:\n".$xml."\n");
                //更新订单数据【通信出错】设为无效订单
                echo 'error';
			}
			else if($notify->data["result_code"] == "FAIL"){
                //此处应该更新一下订单状态，商户自行增删操作
                //$this->log_result($log_name, "【业务出错】:\n".$xml."\n");
                //更新订单数据【通信出错】设为无效订单
                echo 'error';
			}
			else{
                //$this->log_result($log_name, "【支付成功】:\n".$xml."\n");
                //我这里用到一个process方法，成功返回数据后处理，返回地数据具体可以参考微信的文档

                if ($this->process($parameter)) {
                    //处理成功后输出success，微信就不会再下发请求了
                    echo 'success';
                }else {
                    //没有处理成功，微信会间隔的发送请求
                    echo 'error';
                }
			}
		}
	}
    //订单处理
    private function process($parameter) {
        //此处应该更新一下订单状态，商户自行增删操作
        /*
        * 返回的数据最少有以下几个
        * $parameter = array(
            'out_trade_no' => xxx,//商户订单号
            'total_fee' => XXXX,//支付金额
            'openid' => XXxxx,//付款的用户ID
        );
        */

        $type=session('wx_order_type');
				switch ($type) {
					case 'carry':
					$obj=M('orders');
						break;
					case 'nocarry':
					$obj=M('order');
						break;
					case 'pro':
					$obj=M('order_p');
						break;
					
					default:
						# code...
						break;
				}
				$map['id']=session('orderid');
				$save['paystatus']=1;
				$save['paytype']='wx';
				$q=$obj->where($map)->save($save);
				if ($q) {
					 return true;
				}else{
					return false;
				}
       
    }

    function  log_result($file,$word) 
	{
	    $fp = fopen($file,"a");
	    flock($fp, LOCK_EX) ;
	    fwrite($fp,"执行日期：".strftime("%Y-%m-%d-%H：%M：%S",time())."\n".$word."\n\n");
	    flock($fp, LOCK_UN);
	    fclose($fp);
	}
	
 } 